package org.jeecg.common.job.data.controller;

import com.alibaba.fastjson.JSONArray;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.cache.DataCache;
import org.jeecg.common.datasource.jdbc.vo.PageInfo;
import org.jeecg.common.datasource.jdbc.vo.PageSort;
import org.jeecg.common.datasource.jdbc.vo.ResponseData;
import org.jeecg.common.job.JobManageCenter;
import org.jeecg.common.job.data.service.IJobService;
import org.jeecg.common.job.data.vo.JobInfoVo;
import org.jeecg.common.job.data.vo.JobLogVo;
import org.jeecg.common.job.enums.JobConstants;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 底稿定时任务Controller
 *
 * @author zhaoguoqiang
 * @version 2020年01月19 16:10
 */
@Api(value = "底稿定时任务Controller", tags = {"底稿定时任务管理"})
@RestController
@RequestMapping("/sys")
public class JobController {

    private static final Logger LG = LoggerFactory.getLogger("Job");

    @Autowired
    private IJobService jobService;

    @ApiOperation(value = "分页获取定时任务")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "content", value = "查询内容", paramType = "query", dataType = "String")
    })
    @RequestMapping(path = "/job/list", method = RequestMethod.GET)
    public  ResponseData<PageInfo<JobInfoVo>> search(@RequestParam(name = "name", required=false)String name, PageSort pageSort, HttpServletRequest req) {
        PageInfo<JobInfoVo> search = jobService.getJobPage(pageSort, name);
        return ResponseData.success(search);
    }

    @ApiOperation(value = "获取系统所有定时任务")
    @RequestMapping(path = "/job/config", method = RequestMethod.GET)
    public JSONArray searchJobConfig() {
        JSONArray jsonArray = jobService.getJobConfig();
        return jsonArray;
    }

    @ApiOperation(value = "获取所有服务节点")
    @RequestMapping(path = "/job/nodes", method = RequestMethod.GET)
    public JSONArray searchJobNodes() {
        JSONArray nodeArray = new JSONArray();
        String nodeNames = DataCache.getSingleton().getString(JobConstants.CACHE_NODE_NAMES);
        if(StringUtils.isNotBlank(nodeNames)){
            nodeArray = JSONArray.parseArray(nodeNames);
        }
        return nodeArray;
    }

    @ApiOperation(value = "获取定时任务")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "定时任务ID", required = true, paramType = "path", dataType = "Long")
    })
    @RequestMapping(path = "/job/get", method = RequestMethod.GET)
    public ResponseData<JobInfoVo> add(@RequestParam(name = "id", required = true)String id, HttpServletRequest req) {
        return ResponseData.success(jobService.load(id));
    }


    @ApiOperation(value = "添加定时任务")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "定时任务ID", required = true, paramType = "path", dataType = "Long")
    })
    @RequestMapping(path = "/job/add", method = RequestMethod.POST)
    public ResponseData<String> add(@RequestBody JobInfoVo job, HttpServletRequest req) {
        return create(job, req);
    }

    @ApiOperation(value = "修改定时任务")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "定时任务ID", required = true, paramType = "path", dataType = "Long")
    })
    @RequestMapping(path = "/job/edit", method = RequestMethod.POST)
    public ResponseData<String> save(@RequestBody JobInfoVo job, HttpServletRequest req) {
        return update(job, req);
    }

    /**
     * 修改定时任务
     *
     * @param job 定时任务对象
     * @return
     */
    private ResponseData<String> update(JobInfoVo job, HttpServletRequest req) {
        job.setUpdateTime(new Date());
        jobService.update(job, "name", "updateTime");
        LG.info("修改定时任务成功:{}", job.getName());
        return new ResponseData<>("ok");
    }

    /**
     * 保存定时任务
     *
     * @param job 定时任务对象
     * @return
     */
    private ResponseData<String> create(JobInfoVo job, HttpServletRequest req) {
        jobService.save(job);
        LG.info("新增定时任务:{}", job.getName());
        return new ResponseData<>("ok");
    }

    @ApiOperation(value = "删除定时任务")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "定时任务ID", required = true, paramType = "path", dataType = "Long")
    })
    @RequestMapping(path = "/job/delete", method = RequestMethod.GET)
    public ResponseData<String> delete(@RequestParam(name = "id", required = true)String id, HttpServletRequest req) {
        JobInfoVo job = jobService.load(id);
        jobService.delete(id);
        LG.info("删除定时任务:{}", job.getName());
        return new ResponseData<>("ok");
    }

    @ApiOperation(value = "定时任务开关")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "定时任务ID", required = true, paramType = "path", dataType = "Long"),
            @ApiImplicitParam(name = "type", value = "操作类型(0:开启,1:暂停)", required = true, paramType = "path", dataType = "Integer")
    })
    @RequestMapping(path = "/job/pause", method = RequestMethod.GET)
    public ResponseData<String> pause(@RequestParam(name = "id", required = true)String id, HttpServletRequest req) {
        JobInfoVo job = jobService.load(id);
        jobService.switchJob(id, 1);
        LG.info("暂停定时任务:{}", job.getName());
        return new ResponseData<>("ok");
    }

    @ApiOperation(value = "定时任务开关")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "定时任务ID", required = true, paramType = "path", dataType = "Long"),
            @ApiImplicitParam(name = "type", value = "操作类型(0:开启,1:暂停)", required = true, paramType = "path", dataType = "Integer")
    })
    @RequestMapping(path = "/job/resume", method = RequestMethod.GET)
    public ResponseData<String> resume(@RequestParam(name = "id", required = true)String id, HttpServletRequest req) {
        JobInfoVo job = jobService.load(id);
        jobService.switchJob(id, 0);
        LG.info("开启定时任务:{}", job.getName());
        return new ResponseData<>("ok");
    }

    @ApiOperation(value = "手动执行一次")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "定时任务ID", required = true, paramType = "path", dataType = "Long")
    })
    @RequestMapping(path = "/job/exec", method = RequestMethod.GET)
    public ResponseData<String> execJob(@RequestParam(name = "id", required = true) String id, HttpServletRequest req) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        JobInfoVo job = jobService.load(id);
        JobLogVo jobLog = new JobLogVo();
        jobLog.setJobId(job.getId());
        Date btime = new Date();
        try{
            JobManageCenter.execJob(id);
            jobLog.setExecStatus("成功");
            jobLog.setJobReslut("手动执行成功");
        } catch (Exception e){
            jobLog.setExecStatus("失败");
            jobLog.setJobReslut("手动执行失败：" + e.getMessage());
        }
        Date etime = new Date();
        jobLog.setExecBeginTime(btime);
        jobLog.setExecEndTime(etime);
        jobLog.setServerNode(JobConstants.NODE_NAME);
        jobLog.setExecTakeTime(DateUtil.formatTime(etime.getTime() - btime.getTime()));
        jobService.saveJobLog(jobLog);
        LG.info("手动执行定时任务:{}={}", job.getName(), user.getUsername());
        return new ResponseData<>("ok");
    }

    @ApiOperation(value = "查询日志")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "content", value = "查询内容", paramType = "query", dataType = "String")
    })
    @RequestMapping(path = "/job/logs", method = RequestMethod.GET)
    public ResponseData<PageInfo<JobLogVo>> findJobLogs(@RequestParam(name = "content", required=false)String content, PageSort pageSort, HttpServletRequest req) {
        PageInfo<JobLogVo> page = jobService.getJobLogs(pageSort, content);
        return ResponseData.success(page);
    }

}
